15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/host_var_tracker.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 8bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/host_array_buffer_var.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/renderer/pepper/host_globals.h" 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/renderer/pepper/host_resource_var.h" 1158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch#include "content/renderer/pepper/pepper_plugin_instance_impl.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/renderer/pepper/v8object_var.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_var.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ppapi::ArrayBufferVar; 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciusing ppapi::V8ObjectVar; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochnamespace content { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciHostVarTracker::V8ObjectVarKey::V8ObjectVarKey(V8ObjectVar* object_var) 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : instance(object_var->instance()->pp_instance()) { 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci v8::Local<v8::Object> object = object_var->GetHandle(); 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci hash = object.IsEmpty() ? 0 : object->GetIdentityHash(); 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciHostVarTracker::V8ObjectVarKey::V8ObjectVarKey(PP_Instance instance, 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci v8::Handle<v8::Object> object) 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : instance(instance), 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci hash(object.IsEmpty() ? 0 : object->GetIdentityHash()) {} 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciHostVarTracker::V8ObjectVarKey::~V8ObjectVarKey() {} 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool HostVarTracker::V8ObjectVarKey::operator<( 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const V8ObjectVarKey& other) const { 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (instance == other.instance) 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return hash < other.hash; 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return instance < other.instance; 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)HostVarTracker::HostVarTracker() 41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : VarTracker(SINGLE_THREADED), last_shared_memory_map_id_(0) {} 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 43a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochHostVarTracker::~HostVarTracker() {} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new HostArrayBufferVar(size_in_bytes); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer( 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 size_in_bytes, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemoryHandle handle) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new HostArrayBufferVar(size_in_bytes, handle); 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HostVarTracker::AddV8ObjectVar(V8ObjectVar* object_var) { 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci v8::HandleScope handle_scope(object_var->instance()->GetIsolate()); 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(GetForV8Object(object_var->instance()->pp_instance(), 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci object_var->GetHandle()) == object_map_.end()); 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci object_map_.insert(std::make_pair(V8ObjectVarKey(object_var), object_var)); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HostVarTracker::RemoveV8ObjectVar(V8ObjectVar* object_var) { 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci v8::HandleScope handle_scope(object_var->instance()->GetIsolate()); 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ObjectMap::iterator it = GetForV8Object( 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci object_var->instance()->pp_instance(), object_var->GetHandle()); 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(it != object_map_.end()); 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci object_map_.erase(it); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciPP_Var HostVarTracker::V8ObjectVarForV8Object(PP_Instance instance, 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci v8::Handle<v8::Object> object) { 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ObjectMap::const_iterator it = GetForV8Object(instance, object); 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (it == object_map_.end()) 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return (new V8ObjectVar(instance, object))->GetPPVar(); 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return it->second->GetPPVar(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciint HostVarTracker::GetLiveV8ObjectVarsForTest(PP_Instance instance) { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int count = 0; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Use a key with an empty handle to find the v8 object var in the map with 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the given instance and the lowest hash. 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci V8ObjectVarKey key(instance, v8::Handle<v8::Object>()); 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ObjectMap::const_iterator it = object_map_.lower_bound(key); 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci while (it != object_map_.end() && it->first.instance == instance) { 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++count; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ++it; 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return count; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)PP_Var HostVarTracker::MakeResourcePPVarFromMessage( 960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) PP_Instance instance, 970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const IPC::Message& creation_message, 980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int pending_renderer_id, 990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) int pending_browser_id) { 1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // On the host side, the creation message is ignored when creating a resource. 1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // Therefore, a call to this function indicates a null resource. Return the 1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // resource 0. 1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return MakeResourcePPVar(0); 1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ppapi::ResourceVar* HostVarTracker::MakeResourceVar(PP_Resource pp_resource) { 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return new HostResourceVar(pp_resource); 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HostVarTracker::DidDeleteInstance(PP_Instance pp_instance) { 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CheckThreadingPreconditions(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PepperPluginInstanceImpl* instance = 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HostGlobals::Get()->GetInstance(pp_instance); 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci v8::HandleScope handle_scope(instance->GetIsolate()); 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Force delete all var references. ForceReleaseV8Object() will cause 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // this object, and potentially others it references, to be removed from 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |live_vars_|. 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Use a key with an empty handle to find the v8 object var in the map with 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // the given instance and the lowest hash. 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci V8ObjectVarKey key(pp_instance, v8::Handle<v8::Object>()); 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ObjectMap::iterator it = object_map_.lower_bound(key); 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci while (it != object_map_.end() && it->first.instance == pp_instance) { 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ForceReleaseV8Object(it->second); 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci object_map_.erase(it++); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid HostVarTracker::ForceReleaseV8Object(ppapi::V8ObjectVar* object_var) { 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_var->InstanceDeleted(); 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == live_vars_.end()) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second.ref_count = 0; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(iter->second.track_with_no_reference_count == 0); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteObjectInfoIfNecessary(iter); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciHostVarTracker::ObjectMap::iterator HostVarTracker::GetForV8Object( 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PP_Instance instance, 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci v8::Handle<v8::Object> object) { 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::pair<ObjectMap::iterator, ObjectMap::iterator> range = 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci object_map_.equal_range(V8ObjectVarKey(instance, object)); 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (ObjectMap::iterator it = range.first; it != range.second; ++it) { 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (object == it->second->GetHandle()) 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return it; 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return object_map_.end(); 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance, 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemoryHandle handle, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32 size_in_bytes) { 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SharedMemoryMapEntry entry; 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry.instance = instance; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry.handle = handle; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) entry.size_in_bytes = size_in_bytes; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Find a free id for our map. 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (shared_memory_map_.find(last_shared_memory_map_id_) != 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_memory_map_.end()) { 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++last_shared_memory_map_id_; 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_memory_map_[last_shared_memory_map_id_] = entry; 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return last_shared_memory_map_id_; 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HostVarTracker::StopTrackingSharedMemoryHandle( 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int id, 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_Instance instance, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemoryHandle* handle, 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint32* size_in_bytes) { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SharedMemoryMap::iterator it = shared_memory_map_.find(id); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it == shared_memory_map_.end()) 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it->second.instance != instance) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *handle = it->second.handle; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *size_in_bytes = it->second.size_in_bytes; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shared_memory_map_.erase(it); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} // namespace content 190