OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/pepper/host_var_tracker.h" | 5 #include "content/renderer/pepper/host_var_tracker.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "content/renderer/pepper/host_array_buffer_var.h" | 8 #include "content/renderer/pepper/host_array_buffer_var.h" |
9 #include "content/renderer/pepper/host_globals.h" | |
9 #include "content/renderer/pepper/host_resource_var.h" | 10 #include "content/renderer/pepper/host_resource_var.h" |
10 #include "content/renderer/pepper/npobject_var.h" | |
11 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" | 11 #include "content/renderer/pepper/pepper_plugin_instance_impl.h" |
12 #include "content/renderer/pepper/v8object_var.h" | |
12 #include "ppapi/c/pp_var.h" | 13 #include "ppapi/c/pp_var.h" |
13 | 14 |
14 using ppapi::ArrayBufferVar; | 15 using ppapi::ArrayBufferVar; |
15 using ppapi::NPObjectVar; | 16 using ppapi::V8ObjectVar; |
16 | 17 |
17 namespace content { | 18 namespace content { |
18 | 19 |
20 HostVarTracker::V8ObjectVarKey::V8ObjectVarKey(V8ObjectVar* object_var) | |
21 : instance(object_var->instance()->pp_instance()) { | |
22 v8::Handle<v8::Object> object = object_var->GetHandle(); | |
dmichael (off chromium)
2014/08/20 23:09:16
Could you use v8::Local here instead of Handle to
raymes
2014/08/22 08:28:39
Done.
| |
23 hash = object.IsEmpty() ? 0 : object->GetIdentityHash(); | |
24 } | |
25 | |
26 HostVarTracker::V8ObjectVarKey::V8ObjectVarKey(PP_Instance instance, | |
27 v8::Handle<v8::Object> object) | |
28 : instance(instance), | |
29 hash(object.IsEmpty() ? 0 : object->GetIdentityHash()) {} | |
30 | |
31 HostVarTracker::V8ObjectVarKey::~V8ObjectVarKey() {} | |
32 | |
33 | |
34 bool HostVarTracker::V8ObjectVarKey::operator<( | |
35 const V8ObjectVarKey& other) const { | |
36 if (instance == other.instance) | |
37 return hash < other.hash; | |
38 return instance < other.instance; | |
39 } | |
40 | |
41 bool HostVarTracker::V8ObjectVarKey::operator==( | |
42 const V8ObjectVarKey& other) const { | |
43 return instance == other.instance && hash == other.hash; | |
44 } | |
45 | |
19 HostVarTracker::HostVarTracker() | 46 HostVarTracker::HostVarTracker() |
20 : VarTracker(SINGLE_THREADED), last_shared_memory_map_id_(0) {} | 47 : VarTracker(SINGLE_THREADED), last_shared_memory_map_id_(0) {} |
21 | 48 |
22 HostVarTracker::~HostVarTracker() {} | 49 HostVarTracker::~HostVarTracker() {} |
23 | 50 |
24 ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { | 51 ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { |
25 return new HostArrayBufferVar(size_in_bytes); | 52 return new HostArrayBufferVar(size_in_bytes); |
26 } | 53 } |
27 | 54 |
28 ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer( | 55 ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer( |
29 uint32 size_in_bytes, | 56 uint32 size_in_bytes, |
30 base::SharedMemoryHandle handle) { | 57 base::SharedMemoryHandle handle) { |
31 return new HostArrayBufferVar(size_in_bytes, handle); | 58 return new HostArrayBufferVar(size_in_bytes, handle); |
32 } | 59 } |
33 | 60 |
34 void HostVarTracker::AddNPObjectVar(NPObjectVar* object_var) { | 61 void HostVarTracker::AddV8ObjectVar(V8ObjectVar* object_var) { |
35 CheckThreadingPreconditions(); | 62 CheckThreadingPreconditions(); |
36 | 63 v8::HandleScope handle_scope(object_var->instance()->GetIsolate()); |
37 InstanceMap::iterator found_instance = | 64 DCHECK(GetForV8Object(object_var->instance()->pp_instance(), |
38 instance_map_.find(object_var->pp_instance()); | 65 object_var->GetHandle()) == object_map_.end()); |
39 if (found_instance == instance_map_.end()) { | 66 object_map_.insert(std::make_pair(V8ObjectVarKey(object_var), object_var)); |
40 // Lazily create the instance map. | |
41 DCHECK(object_var->pp_instance() != 0); | |
42 found_instance = | |
43 instance_map_.insert(std::make_pair( | |
44 object_var->pp_instance(), | |
45 linked_ptr<NPObjectToNPObjectVarMap>( | |
46 new NPObjectToNPObjectVarMap))).first; | |
47 } | |
48 NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); | |
49 | |
50 DCHECK(np_object_map->find(object_var->np_object()) == np_object_map->end()) | |
51 << "NPObjectVar already in map"; | |
52 np_object_map->insert(std::make_pair(object_var->np_object(), object_var)); | |
53 } | 67 } |
54 | 68 |
55 void HostVarTracker::RemoveNPObjectVar(NPObjectVar* object_var) { | 69 void HostVarTracker::RemoveV8ObjectVar(V8ObjectVar* object_var) { |
56 CheckThreadingPreconditions(); | 70 CheckThreadingPreconditions(); |
57 | 71 v8::HandleScope handle_scope(object_var->instance()->GetIsolate()); |
58 InstanceMap::iterator found_instance = | 72 ObjectMap::iterator it = GetForV8Object( |
59 instance_map_.find(object_var->pp_instance()); | 73 object_var->instance()->pp_instance(), object_var->GetHandle()); |
60 if (found_instance == instance_map_.end()) { | 74 DCHECK(it != object_map_.end()); |
61 NOTREACHED() << "NPObjectVar has invalid instance."; | 75 object_map_.erase(it); |
62 return; | |
63 } | |
64 NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); | |
65 | |
66 NPObjectToNPObjectVarMap::iterator found_object = | |
67 np_object_map->find(object_var->np_object()); | |
68 if (found_object == np_object_map->end()) { | |
69 NOTREACHED() << "NPObjectVar not registered."; | |
70 return; | |
71 } | |
72 if (found_object->second != object_var) { | |
73 NOTREACHED() << "NPObjectVar doesn't match."; | |
74 return; | |
75 } | |
76 np_object_map->erase(found_object); | |
77 } | 76 } |
78 | 77 |
79 NPObjectVar* HostVarTracker::NPObjectVarForNPObject(PP_Instance instance, | 78 PP_Var HostVarTracker::V8ObjectVarForV8Object(PP_Instance instance, |
80 NPObject* np_object) { | 79 v8::Handle<v8::Object> object) { |
81 CheckThreadingPreconditions(); | 80 CheckThreadingPreconditions(); |
82 | 81 ObjectMap::const_iterator it = GetForV8Object(instance, object); |
83 InstanceMap::iterator found_instance = instance_map_.find(instance); | 82 if (it == object_map_.end()) |
84 if (found_instance == instance_map_.end()) | 83 return (new V8ObjectVar(instance, object))->GetPPVar(); |
85 return NULL; // No such instance. | 84 return it->second->GetPPVar(); |
86 NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); | |
87 | |
88 NPObjectToNPObjectVarMap::iterator found_object = | |
89 np_object_map->find(np_object); | |
90 if (found_object == np_object_map->end()) | |
91 return NULL; // No such object. | |
92 return found_object->second; | |
93 } | 85 } |
94 | 86 |
95 int HostVarTracker::GetLiveNPObjectVarsForInstance(PP_Instance instance) const { | 87 int HostVarTracker::GetLiveV8ObjectVarsForInstance(PP_Instance instance) { |
96 CheckThreadingPreconditions(); | 88 CheckThreadingPreconditions(); |
97 | 89 int count = 0; |
98 InstanceMap::const_iterator found = instance_map_.find(instance); | 90 ObjectMap::const_iterator it = object_map_.lower_bound( |
99 if (found == instance_map_.end()) | 91 V8ObjectVarKey(instance, v8::Handle<v8::Object>())); |
dmichael (off chromium)
2014/08/20 23:09:15
suggestion: equal_range might be clearer and simpl
raymes
2014/08/22 08:28:39
I thought about this a bit. It means you have to w
dmichael (off chromium)
2014/08/22 16:28:46
I don't see why or how you would pass two keys? I'
raymes
2014/08/25 01:40:00
Sorry it was late Friday afternoon and I was not t
dmichael (off chromium)
2014/08/25 17:31:11
Ah, I completely missed that detail. Maybe you can
raymes
2014/08/26 05:15:11
Done.
| |
100 return 0; | 92 while (it != object_map_.end() && it->first.instance == instance) { |
101 return static_cast<int>(found->second->size()); | 93 ++count; |
94 ++it; | |
95 } | |
96 return count; | |
102 } | 97 } |
103 | 98 |
104 PP_Var HostVarTracker::MakeResourcePPVarFromMessage( | 99 PP_Var HostVarTracker::MakeResourcePPVarFromMessage( |
105 PP_Instance instance, | 100 PP_Instance instance, |
106 const IPC::Message& creation_message, | 101 const IPC::Message& creation_message, |
107 int pending_renderer_id, | 102 int pending_renderer_id, |
108 int pending_browser_id) { | 103 int pending_browser_id) { |
109 // On the host side, the creation message is ignored when creating a resource. | 104 // On the host side, the creation message is ignored when creating a resource. |
110 // Therefore, a call to this function indicates a null resource. Return the | 105 // Therefore, a call to this function indicates a null resource. Return the |
111 // resource 0. | 106 // resource 0. |
112 return MakeResourcePPVar(0); | 107 return MakeResourcePPVar(0); |
113 } | 108 } |
114 | 109 |
115 ppapi::ResourceVar* HostVarTracker::MakeResourceVar(PP_Resource pp_resource) { | 110 ppapi::ResourceVar* HostVarTracker::MakeResourceVar(PP_Resource pp_resource) { |
116 return new HostResourceVar(pp_resource); | 111 return new HostResourceVar(pp_resource); |
117 } | 112 } |
118 | 113 |
119 void HostVarTracker::DidDeleteInstance(PP_Instance instance) { | 114 void HostVarTracker::DidDeleteInstance(PP_Instance pp_instance) { |
120 CheckThreadingPreconditions(); | 115 CheckThreadingPreconditions(); |
121 | 116 |
122 InstanceMap::iterator found_instance = instance_map_.find(instance); | 117 PepperPluginInstanceImpl* instance = |
123 if (found_instance == instance_map_.end()) | 118 HostGlobals::Get()->GetInstance(pp_instance); |
124 return; // Nothing to do. | 119 v8::HandleScope handle_scope(instance->GetIsolate()); |
125 NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get(); | 120 // Force delete all var references. ForceReleaseV8Object() will cause |
126 | |
127 // Force delete all var references. ForceReleaseNPObject() will cause | |
128 // this object, and potentially others it references, to be removed from | 121 // this object, and potentially others it references, to be removed from |
129 // |np_object_map|. | 122 // |live_vars_|. |
130 while (!np_object_map->empty()) { | 123 ObjectMap::iterator it = object_map_.lower_bound( |
131 ForceReleaseNPObject(np_object_map->begin()->second); | 124 V8ObjectVarKey(pp_instance, v8::Handle<v8::Object>())); |
125 while (it != object_map_.end() && it->first.instance == pp_instance) { | |
126 ForceReleaseV8Object(it->second); | |
127 object_map_.erase(it++); | |
132 } | 128 } |
133 | |
134 // Remove the record for this instance since it should be empty. | |
135 DCHECK(np_object_map->empty()); | |
136 instance_map_.erase(found_instance); | |
137 } | 129 } |
138 | 130 |
139 void HostVarTracker::ForceReleaseNPObject(ppapi::NPObjectVar* object_var) { | 131 void HostVarTracker::ForceReleaseV8Object(ppapi::V8ObjectVar* object_var) { |
140 object_var->InstanceDeleted(); | 132 object_var->InstanceDeleted(); |
141 VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID()); | 133 VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID()); |
142 if (iter == live_vars_.end()) { | 134 if (iter == live_vars_.end()) { |
143 NOTREACHED(); | 135 NOTREACHED(); |
144 return; | 136 return; |
145 } | 137 } |
146 iter->second.ref_count = 0; | 138 iter->second.ref_count = 0; |
147 DCHECK(iter->second.track_with_no_reference_count == 0); | 139 DCHECK(iter->second.track_with_no_reference_count == 0); |
148 DeleteObjectInfoIfNecessary(iter); | 140 DeleteObjectInfoIfNecessary(iter); |
149 } | 141 } |
150 | 142 |
143 HostVarTracker::ObjectMap::iterator HostVarTracker::GetForV8Object( | |
144 PP_Instance instance, | |
145 v8::Handle<v8::Object> object) { | |
146 V8ObjectVarKey key(instance, object); | |
147 ObjectMap::iterator it = object_map_.lower_bound(key); | |
148 | |
149 while (it != object_map_.end() && it->first == key) { | |
150 if (object == it->second->GetHandle()) | |
151 return it; | |
152 ++it; | |
153 } | |
154 return object_map_.end(); | |
155 } | |
156 | |
151 int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance, | 157 int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance, |
152 base::SharedMemoryHandle handle, | 158 base::SharedMemoryHandle handle, |
153 uint32 size_in_bytes) { | 159 uint32 size_in_bytes) { |
154 SharedMemoryMapEntry entry; | 160 SharedMemoryMapEntry entry; |
155 entry.instance = instance; | 161 entry.instance = instance; |
156 entry.handle = handle; | 162 entry.handle = handle; |
157 entry.size_in_bytes = size_in_bytes; | 163 entry.size_in_bytes = size_in_bytes; |
158 | 164 |
159 // Find a free id for our map. | 165 // Find a free id for our map. |
160 while (shared_memory_map_.find(last_shared_memory_map_id_) != | 166 while (shared_memory_map_.find(last_shared_memory_map_id_) != |
(...skipping 15 matching lines...) Expand all Loading... | |
176 if (it->second.instance != instance) | 182 if (it->second.instance != instance) |
177 return false; | 183 return false; |
178 | 184 |
179 *handle = it->second.handle; | 185 *handle = it->second.handle; |
180 *size_in_bytes = it->second.size_in_bytes; | 186 *size_in_bytes = it->second.size_in_bytes; |
181 shared_memory_map_.erase(it); | 187 shared_memory_map_.erase(it); |
182 return true; | 188 return true; |
183 } | 189 } |
184 | 190 |
185 } // namespace content | 191 } // namespace content |
OLD | NEW |